package com.ruoyi.file.controller;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.ruoyi.common.core.utils.IPMSUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.ibatis.annotations.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.file.FileUtils;
import com.ruoyi.file.service.ISysFileService;
import com.ruoyi.system.api.domain.SysFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 文件请求处理
 * 
 * @author ruoyi
 */
@RestController
public class SysFileController
{
    private static final Logger log = LoggerFactory.getLogger(SysFileController.class);

    @Autowired
    private ISysFileService sysFileService;

    /**
     * 文件上传请求
     */
    @PostMapping("upload")
    public R<SysFile> upload(MultipartFile file)
    {
        try
        {
            // 上传并返回访问地址
            String url = sysFileService.uploadFile(file);
            SysFile sysFile = new SysFile();
            sysFile.setName(FileUtils.getName(url));
            sysFile.setUrl(url);
            return R.ok(sysFile);
        }
        catch (Exception e)
        {
            log.error("上传文件失败", e);
            return R.fail(e.getMessage());
        }
    }


    private static  final String BUCKET_NAME = "aliyun-shelly-oss";
    private static  final String URL_PREFIX = "https://aliyun-shelly-oss.oss-cn-chengdu.aliyuncs.com";

    //注入阿里云客户端
    @Resource
    private OSSClient ossClient;

    //上传文件到阿里云OSS
    @PostMapping("/aliyunUpload")
    public AjaxResult aliyunUpload(MultipartFile file){

        System.out.println(file);

        String fileName = file.getOriginalFilename();
        //1、获取文件名
        //2、获取文件流对象
        try {
            InputStream inputStream = file.getInputStream();
            //3、阿里云上传
            /*参数1：桶名字
             *参数2：文件名(uuid)
             *参数3：流对象
             */
            ossClient.putObject(BUCKET_NAME,fileName,inputStream);

            //4、设置文件过期时间(30天之后的日期)
            Date date = new Date(new Date().getTime() + 1000 * 60 * 60 * 24 * 30);
            //5、上传文件指定过期时间，返回uri
            //url: http://xxx.com/xx/xx/xx.html
            //uri: /xx/xx/xx.html
            URL url = ossClient.generatePresignedUrl(BUCKET_NAME, fileName, date);
            System.out.println( URL_PREFIX + url.getPath());
            UploadResult uploadResult = new UploadResult();
            uploadResult.setFileName(fileName);
            uploadResult.setUrl(URL_PREFIX + url.getPath());
            return AjaxResult.success("上传成功",uploadResult);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    //删除文件
    @DeleteMapping("/del/{fileName}")
    public  AjaxResult del(@PathVariable("fileName") String fileName){
        ossClient.deleteObject(BUCKET_NAME,fileName);
        return AjaxResult.success("删除成功");
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class UploadResult{
        private  String fileName;
        private  String url;
    }


    @Value("${spring.cloud.alicloud.access-key}")
    private String accessId;
    @Value("${spring.cloud.alicloud.secret-key}")
    private String accessKey;
    @Value("${spring.cloud.alicloud.oss.endpoint}")
    private String endpoint;
    @Value("${spring.cloud.alicloud.bucket-name}")
    private String bucket;

    //服务返回oss签名 ，web拿到签名后，上传文件到OSS
    @GetMapping("/ossSign")
    public AjaxResult  ossSign(){
        // host的格式为 bucketname.endpoint
        String host = "https://" + bucket + "." + endpoint;

        // callbackUrl为 上传回调服务器的URL，请将下面的IP和Port配置为您自己的真实信息。
        String callbackUrl = "http://localhost:9300/callback";

        // 用户上传文件时指定的前缀。
        String dir = "itsource";

        try {
            long expireTime = 30;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);

            // PostObject请求最大可支持的文件大小为5 GB，即CONTENT_LENGTH_RANGE为5*1024*1024*1024。
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            Map<String, String> respMap = new LinkedHashMap<String, String>();
            respMap.put("accessid", accessId);
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("host", host);
            respMap.put("expire", String.valueOf(expireEndTime / 1000));
            return AjaxResult.success(respMap);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        } finally {
            ossClient.shutdown();
        }
        return null;
    }
}